# -*- coding: utf-8 -*-
from QuModLibs.Server import *
from QuModLibs.Modules.Services.Server import BaseService
from QuModLibs.Modules.Thread.Server import RUN_IN_MAIN_THREAD
from BiliDanmuBot import BiliDanmuBot, MsgModel
from Config import BIND_ROOM_ID
lambda: "By Zero123"

@BaseService.Init
class BiliDanmuService(BaseService):
    """ BILI弹幕管理服务 """
    def __init__(self):
        BaseService.__init__(self)
        self.bot = BiliDanmuBot(BIND_ROOM_ID)
        self.bot.regFunction("GET_MSG", self._GET_MSG)
        self.messageQueue = []  # type: list[MsgModel]
        """ 待处理消息队列 确保大量弹幕的情况下不会瞬间处理 """
        self.initLoadFinish = False

    def onCreate(self):
        BaseService.onCreate(self)
        self.bot.start()

    def _GET_MSG(self, msgJoData):
        # type: (dict) -> None
        # 子线程内处理数据模型并转发到游戏线程
        msgModel = MsgModel(msgJoData)
        RUN_IN_MAIN_THREAD(lambda: self._onUserSendMsg(msgModel))

    def _onUserSendMsg(self, msgModel=MsgModel()):
        # 内部处理
        self.messageQueue.append(msgModel)
        self.onUserSendMsg(msgModel)

    def onUserSendMsg(self, msgModel=MsgModel()):
        """ B站用户发送弹幕消息事件 """
        print(msgModel)

    def onMsgQueueLoad(self, msgModel=MsgModel()):
        """ 消息从队列加载时触发 避免同时处理太多消息导致的卡顿 """
        self.msgModelToAllPlayer(msgModel)

    @BaseService.Listen(Events.ClientLoadAddonsFinishServerEvent)
    def ClientLoadAddonsFinishServerEvent(self, _={}):
        self.initLoadFinish = True

    def onServiceUpdate(self):
        BaseService.onServiceUpdate(self)
        if not self.initLoadFinish:
            return
        # 队列化分批处理消息
        oldMsgList = self.messageQueue
        length = len(oldMsgList)
        useCount = int(round(length * 0.1 + 1, 2))
        self.messageQueue = self.messageQueue[useCount:]
        if useCount > length:
            return
        for i in range(useCount):
            msgObj = oldMsgList[i]
            self.onMsgQueueLoad(msgObj)

    def msgToAllPlayer(self, msg=""):
        """ 全玩家消息发送 """
        for playerId in serverApi.GetPlayerList():
            comp = serverApi.GetEngineCompFactory().CreateMsg(playerId)
            comp.NotifyOneMessage(playerId, msg, "§f")

    def msgModelToAllPlayer(self, msgModel=MsgModel()):
        """ 全玩家Model消息发送 """
        comp = serverApi.GetEngineCompFactory().CreateGame(levelId)
        if not comp.CheckNameValid(msgModel.nickname):
            msgModel.nickname = "***"
        if not comp.CheckWordsValid(msgModel.text):
            msgModel.text = "***"
        msgText = "<{}> {}".format(msgModel.nickname, msgModel.text)
        if msgModel.isadmin:
            # 房管成员特殊处理
            self.msgToAllPlayer("§l§b"+msgText)
            return
        self.msgToAllPlayer(msgText)

    def onServiceStop(self):
        BaseService.onServiceStop(self)
        self.bot.stop()